package com.dean.service;

import cn.hutool.core.util.StrUtil;
import com.dean.constants.DeanUiConstants;
import com.dean.dao.DeanToolDao;
import com.dean.entity.DeanDbConnInfo;
import com.dean.entity.DeanImportInfo;
import com.dean.entity.ExcelQueryResult;
import com.dean.entity.SysDbConnInfo;
import com.dean.exception.DeanRuntimeException;
import com.dean.listener.DeanEasyExcelListener;
import com.dean.utils.DeanEasyExcelUtils;
import com.dean.utils.DeanJdbcUtils;
import com.dean.utils.GenExcelUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.util.List;
import java.util.UUID;

/**
 * @ClassName ExcelExportService
 * @Description excel导出服务类
 * @Author dean
 * @Date 2021/11/16 10:33
 */
public class ExcelOptService {
    private static final Logger logger = LoggerFactory.getLogger(ExcelOptService.class);

    // 静态内部类实现单例模式
    // 懒汉式 jvm 保证线程安全  jvm 保证每个类只加载一次 内部类只有在调用的时候才加载
    private ExcelOptService(){}

    private static class ExcelOptServiceHolder{
        private final static ExcelOptService INSTANCE = new ExcelOptService();
    }

    public static ExcelOptService getInstance(){
        return ExcelOptServiceHolder.INSTANCE;
    }
    /**
     * excel 文件导出 批量任务
     * @param connectInfo
     * @param filePath
     * @param sqls
     */
    public void excelExport(SysDbConnInfo connectInfo, String filePath, String [] sqls){
        // 文件目录若不存在 则直接新建
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        for (String sql : sqls) {
            String tmpName="";
            if (sql.lastIndexOf("###") > -1) {
                tmpName = sql.substring(sql.lastIndexOf("###") + 3);
                sql = sql.substring(0, sql.lastIndexOf("###"));
            }else {
                tmpName = UUID.randomUUID().toString();
            }
            excelExport(connectInfo,sql,filePath+ File.separator +tmpName+".xlsx");
        }
    }

    /**
     * excel 文件导出 单文件
     * @param connectInfo
     * @param sql
     * @param fileName
     */
    public void excelExport(SysDbConnInfo connectInfo, String sql, String fileName){
        // 校验sql
        if(StrUtil.isBlank(sql)){
            DeanRuntimeException.throwException(2001,"校验错误,参数[sql]不能为空");
        }
        if(!sql.startsWith(DeanUiConstants.START_SELECT_CHAR)){
            DeanRuntimeException.throwException(2005,"校验错误,不支持的sql操作");
        }
        // 如果文件名称为空,则自动生成文件名称
        if(StrUtil.isBlank(fileName)){
            DeanRuntimeException.throwException(2001,"校验错误,参数[fileName]不能为空");
        }
        connectInfo = DeanToolDao.getInstance().queryConnInfo(connectInfo.getConnName());
        // 生成 导出任务
        DeanExecutorService.producer("excel export task, sql:"+sql);
        GenExcelUtils genExcelUtils = new GenExcelUtils(connectInfo,sql,fileName);
        DeanExecutorService.getInstance().execute(genExcelUtils);
    }

    public void excelExportByCMD(SysDbConnInfo connectInfo, String sql, String fileName){
        // 校验sql
        if(StrUtil.isBlank(sql)){
            DeanRuntimeException.throwException(2001,"校验错误,参数[sql]不能为空");
        }
        if(!sql.startsWith(DeanUiConstants.START_SELECT_CHAR)){
            DeanRuntimeException.throwException(2005,"校验错误,不支持的sql操作");
        }
        // 如果文件名称为空,则自动生成文件名称
        if(StrUtil.isBlank(fileName)){
            DeanRuntimeException.throwException(2001,"校验错误,参数[fileName]不能为空");
        }
        // 生成 导出任务
        ExcelQueryResult result = DeanJdbcUtils.query(connectInfo,sql);
        DeanEasyExcelUtils.writeExcel(fileName,result);
    }

    public void importExcel(SysDbConnInfo connectInfo, List<File> fileNames, DeanImportInfo importInfo){
        connectInfo = DeanToolDao.getInstance().queryConnInfo(connectInfo.getConnName());
        for (File file : fileNames) {
            String fileName = file.getPath();
            importExcel(connectInfo,fileName,importInfo);
        }
    }

    private void importExcel(SysDbConnInfo connectInfo, String fileName, DeanImportInfo importInfo){
        // 校验sql
        if(StrUtil.isBlank(fileName)){
            DeanRuntimeException.throwException(2001,"校验错误,参数[fileName]不能为空");
        }
        DeanEasyExcelListener deanEasyExcelListener = new DeanEasyExcelListener();
        deanEasyExcelListener.setConnInfo(connectInfo);
        deanEasyExcelListener.setImportInfo(importInfo);
        DeanEasyExcelUtils.saveAllSheetContent(fileName,deanEasyExcelListener);
    }

}
